package com.itheima.huikebackend.service.impl;

//import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.huikebackend.context.BaseContext;
import com.itheima.huikebackend.dto.SysUserDTO;
import com.itheima.huikebackend.dto.SysUserLoginDTO;
import com.itheima.huikebackend.dto.SysUserPageDTO;
import com.itheima.huikebackend.dto.SysUserUpdateDTO;
import com.itheima.huikebackend.entity.SysDept;
import com.itheima.huikebackend.entity.SysMenu;
import com.itheima.huikebackend.entity.SysRole;
import com.itheima.huikebackend.entity.SysUser;
import com.itheima.huikebackend.enums.RoleKeyEnum;
import com.itheima.huikebackend.exception.LoginFailedException;
import com.itheima.huikebackend.mapper.SysDeptMapper;
import com.itheima.huikebackend.mapper.SysMenuMapper;
import com.itheima.huikebackend.mapper.SysRoleMapper;
import com.itheima.huikebackend.mapper.SysUserMapper;
import com.itheima.huikebackend.service.SysUserService;
import com.itheima.huikebackend.vo.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.time.LocalDate;
import java.util.*;

/**
 * @author iTaotao
 * @version 1.0
 * @date 2023/08/07 17:05:31
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysUserServiceImpl implements SysUserService {

    private final SysUserMapper sysUserMapper;
    private final SysDeptMapper sysDeptMapper;

    private final SysRoleMapper sysRoleMapper;
    private final SysMenuMapper sysMenuMapper;

    @Override
    public SysUser login(SysUserLoginDTO sysUserLoginDTO) {
        String username = sysUserLoginDTO.getUsername();
        String password = sysUserLoginDTO.getPassword();
        String code = sysUserLoginDTO.getCode();

        SysUser sysUser = sysUserMapper.selectSysUserByUserName(username);
        Integer count = sysUserMapper.selectCode(code);

        if (Objects.isNull(sysUser)) {
            throw new LoginFailedException("用户不存在");
        }
        if (!Objects.equals(password, sysUser.getPassword())) {
            throw new LoginFailedException("密码错误");
        }
        if (count == 0) {
            throw new LoginFailedException("验证码错误");
        }


        return sysUser;

    }

    @Override
    public CaptchaImageVO code() {
//        //数据库code数据过多进行删除操作
//        if (sysUserMapper.selectCount() > 50){
//            sysUserMapper.delete();
//        }
        CaptchaImageVO captchaImageVO = new CaptchaImageVO();
        //圆圈干扰验证码
        //定义图形验证码的长、宽、验证码字符数、干扰元素个数
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);
        //图形验证码写出, 正确答案
        String code = captcha.getCode();
        //string
        String imageBase64 = captcha.getImageBase64();
        //生成uuid，将这个uuid与验证码正确值绑定
        // TODO 存入redis中
        String uuid = UUID.randomUUID().toString();
        sysUserMapper.insertCode(code, uuid);
        //封装返回
        captchaImageVO.setCode(200);
        captchaImageVO.setMsg("操作成功");
        captchaImageVO.setUuid(uuid);
        captchaImageVO.setImg(imageBase64);

        return captchaImageVO;
    }


    @Override
    public List<SysMenu> selectSysMenus() {
        List<SysMenu> sysMenus = sysUserMapper.selectSysMenus();
        return sysMenus;
    }

    @Override
    public Map<String, Object> getUserInfo(String currentId) {
        Map<String, Object> res = new HashMap<>();

        SysUser sysUser = sysUserMapper.selectUserInfoById(currentId);
        SysDept sysDept = sysDeptMapper.selectDeptInfoById(sysUser.getDeptId());
        List<SysRole> sysRoleList = sysRoleMapper.selectRoleInfoById(sysUser.getUserId());

        SysUserVO sysUserVO = new SysUserVO();
        BeanUtils.copyProperties(sysUser, sysUserVO);

        DeptVO deptVO = new DeptVO();
        BeanUtils.copyProperties(sysDept, deptVO);
        sysUserVO.setDept(deptVO);

        List<RoleVO> roleVOList = new ArrayList<>();
        for (SysRole role : sysRoleList) {
            RoleVO roleVO = new RoleVO();
            BeanUtils.copyProperties(role, roleVO);
            roleVOList.add(roleVO);
        }
        sysUserVO.setRoles(roleVOList);

        // user
        res.put("user", sysUserVO);

        // roles
        boolean isAdmin = false;
        List<String> roles = new ArrayList<>();
        for (RoleVO vo : roleVOList) {
            roles.add(vo.getRoleKey());
            if (RoleKeyEnum.ADMIN.value.equals(vo.getRoleKey())) {
                isAdmin = true;
            }
        }
        sysUserVO.setAdmin(isAdmin);
        res.put("roles", roles);

        if (!isAdmin) {
            // permissions
            List<SysMenu> permissions = sysMenuMapper.selectMenuByRoleId(sysRoleList);
            List<String> preList = new ArrayList<>();
            for (SysMenu permission : permissions) {
                if (StringUtils.hasLength(permission.getPerms())) {
                    preList.add(permission.getPerms());
                }
            }
            res.put("permissions", preList);
        } else {
            List<String> adminRoles = new ArrayList<>();
            adminRoles.add("*:*:*");
            res.put("permissions", adminRoles);
        }
        return res;
    }

    @Override
    public Map<String, Object> selectUserByPage(SysUserPageDTO userPageDTO) {


        PageHelper.startPage(userPageDTO.getPageNum(), userPageDTO.getPageSize());
        Page<SysUserViewVO> page = sysUserMapper.selectByPage(userPageDTO);

        //TODO
        //添加查询部门信息

        Map<String, Object> map = new HashMap<>();
        map.put("total", page.getTotal());
        map.put("rows", page.getResult());
        return map;


    }

    @Override
    public Map<String, Object> findRoleAndPost() {

        List<SysPostVO> postVOList = sysUserMapper.selectSysPost();
        List<SysRoleVO> roleVOList = sysUserMapper.selectSysRole();

//        List<SysPostVO> postList = postVOList.stream().peek(s -> s.setFlag(false)).collect(Collectors.toList());
//
//        List<SysRoleVO> roleList = roleVOList.stream().peek(s -> {
//            s.setAdmin(false);
//            s.setFlag(false);
//        }).collect(Collectors.toList());

        Map<String,Object> map = new HashMap<>();
        map.put("roles",roleVOList);
        map.put("posts",postVOList);

        return map;
    }

    @Override
    public void addUser(SysUserDTO sysUserDTO) {
        SysUser sysUser = new SysUser();
        
        BeanUtils.copyProperties(sysUserDTO,sysUser);
        sysUser.setUserType("00");
        sysUser.setDelFlag("0");
        sysUser.setCreateBy(findUserById( BaseContext.getCurrentId()).getUserName());
        sysUser.setCreateTime(LocalDate.now());
        sysUser.setUpdateBy(findUserById( BaseContext.getCurrentId()).getUserName());
        sysUser.setUpdateTime(LocalDate.now());

        sysUserMapper.insertUser(sysUser);
    }

    @Override
    public void deleteUser(Long id) {
        sysUserMapper.deleteUser(id);
    }

    @Override
    public SysUserEchoVO findUserById(String id){
        return sysUserMapper.selectUserById(id);
    }

    @Override
    public void updateUserPassword(SysUserUpdateDTO sysUserUpdateDTO) {
        sysUserMapper.updateUserPassword(sysUserUpdateDTO);
    }

    @Override
    public void export(HttpServletResponse response) {
        try {
            InputStream inp = this.getClass().getClassLoader().getResourceAsStream("user.xlsx");
            assert inp != null;
            Workbook wb = WorkbookFactory.create(inp);
            Sheet sheetAt0 = wb.getSheetAt(0);

            List<SysUserViewVO> list = sysUserMapper.selectAllUser();

            for (int i = 0; i < list.size(); i++) {
                SysUserViewVO sysUserViewVO = list.get(i);
                Row row = sheetAt0.getRow(i+2);

                Cell cell1 = row.getCell(1);
                Cell cell2 = row.getCell(2);
                Cell cell3 = row.getCell(3);
                Cell cell4 = row.getCell(4);
                Cell cell5 = row.getCell(5);
                Cell cell6 = row.getCell(6);
                Cell cell7 = row.getCell(7);
                Cell cell8 = row.getCell(8);
                Cell cell9 = row.getCell(9);
                Cell cell10 = row.getCell(10);

                cell1.setCellValue(sysUserViewVO.getNickName());
                //cell2.setCellValue(sysUserViewVO.getDeptVO().getDeptName());
                cell3.setCellValue(sysUserViewVO.getPhonenumber());
                cell4.setCellValue(sysUserViewVO.getEmail());
                cell5.setCellValue(sysUserViewVO.getUserName());
                cell6.setCellValue(Objects.equals(0,sysUserViewVO.getSex())? "男":"女");
                cell7.setCellValue(Objects.equals(0,sysUserViewVO.getStatus())? "正常":"停用");
                cell8.setCellValue("null");
                cell9.setCellValue("null");
                cell10.setCellValue(sysUserViewVO.getRemark());
            }

            ServletOutputStream outputStream = response.getOutputStream();
            wb.write(outputStream);
        } catch (Exception e) {
            log.error("表格导出失败:{}",e.getMessage());
        }
    }

}

